/**
*  \file term.c
*
*  \brief
*
*  \author Dajin.li dajin.li@Linde-China.com
*
*
*/

/*===============================================[ private includes  ]================================================*/
#include "../cfg/prj.h"
#include "../specs/specs.h"
#include "../specs/specs_hw.h"
#include "../parameter/mon.h"
#include "../parameter/calibration.h"
#include "../paragen/paragen.h"
#include "../switch/switch.h"
#include "../mcu/mcu.h"
#include "../app/app.h"
#include "../input/input.h"
#include "../output/output.h"
#include "../cancom/cancom.h"
#include "../common/commdef.h"
#include "../supervisor/supervisor_cfg.h"
#include "../kwp/kwp_rc.h"
#include "../secacc/secacc.h"
#include "../timerecorder/timerecorder.h"
/*===============================================[ private defines   ]================================================*/



/*===============================================[ private datatypes ]================================================*/

/*===============================================[ private variables ]================================================*/

/*===============================================[ public variables  ]================================================*/




/*===============================================[ private functions ]================================================*/
VO te_Conv2Control(VO)
{

}



/**
*  calibration parameter handling
*  \brief  resolution calculation for corresponding calibration parameter
*
*  \param  cal_par    calibration parameter
*  \param  cal_min    min valid calibration parameter value
*  \param  cal_max    max valid calibration parameter value
*  \param  def_resol  default calibration resolution
*  \param  cal_error  pointer error: calibration parameter value invalid
*
*  \return resolution
*/
F32 calpar2resol(S16 cal_par  ,    /* calibration parameter (e.g. EEPROM)         */
                 S16 cal_min  ,    /* min valid calibration parameter value       */
                 S16 cal_max  ,    /* max valid calibration parameter value       */
                 F32 cal_vol  ,    /* variant specific calibration voltage value  */
                 F32 def_resol,    /* default calibration resolution              */
                 BO* cal_error )   /* error: calibration paramter value invalid   */
{
                                                                                                                      /*
   check calibration parameter value of its valid range                                                               */
   if ((cal_par < cal_min) ||
       (cal_par > cal_max))
   {
      *cal_error = TRUE;
      return def_resol;                   /* default resolution                  */
   }
   else
   {
      if (cal_par <= 0)                   /* avoid division by zero or negative  */
      {
         *cal_error = TRUE;
         return def_resol;                /* default resolution                  */
      }
      else
      {
         return (cal_vol/((F32)cal_par)); /* calculate resolution                */
      }
   }
}

VO term_initalize_basic(VO)
{

   specs_initialize_hardware(48);  /* Production-Parameter "te_BattType_par" is known afer ParInitAll "BasicParMenu" */

   te_Conv2Control();
   /** te_Conv2Assist(); ** INHIB ASSIST **/
}


VO term_initalize_speci(S16 num, S16 *buf)
{
   specs_initialize(KCPC_48V_4W);

   te_Conv2Control();
   /** te_Conv2Assist(); ** INHIB ASSIST **/
}

VO term_initalize_assist(VO)
{

   te_Conv2Control();
   /** te_Conv2Assist();   ** INHIB ASSIST **/
}


/*====================================================================================================================*/

/**
*  Initialization.
*
*  Initialize the term module.
*
*  \return RC_SUCCESS if successfull..
*/
RC term_initialize(VO)
{
   /* basic (truck type independant) parameter initialisation           */
   /* caution !                                                         */
   /* basic parameter must be initialised before specific parameter !   */
   /* because specific parameter may depend on basic parameters like    */
   /* factory parameter or performance mode parameter                   */
   term_initalize_basic();
   term_initalize_assist();

   /* truck specific parameter initialisation                           */
   /* .. after basic parameter initialisation !                         */
   term_initalize_speci(0, NIL);

   return RC_SUCCESS;
}

S16 ApplDiagRequest(S16 req, S16 mode)
{
    U16 data = 0;
    U16 index = 0;

    switch (req)
    {
        /*teachin of accelerator1 signal at pedal min position*/
        case REQ_TEACH_STEER_START:
        case REQ_TEACH_ACCELERATOR1_START:
        case REQ_TEACH_ACCELERATOR2_START:
        case REQ_TEACH_LIFT_POTENTIOMETER_START:
            if (input_data.park_break_switch < 0)                      /* handbrake released */
            {
                return RSP_NOHBRAKE;
            }
            if (input_data.seat_switch_1 < 0)                         /* seat not activated */
            {
                return RSP_NOSEAT;
            }

            return KWP_RESPONSE_CODE_SUCCESS;
            break;
        
        case REQ_TEACH_ACCELERATOR1_MIN:

            if (input_data.park_break_switch < 0)                      /* handbrake released */
            {
                return RSP_NOHBRAKE;
            }
            if (input_data.seat_switch_1 < 0)                         /* seat not activated */
            {
                return RSP_NOSEAT;
            }

            index = 0x03E9;
            data = input_data.adc_voltage[mcu_adc_Accelerator1] / can_resol_voltage_sensor;
            break;

        /*teachin of accelerator1 signal at pedal max position*/
        case REQ_TEACH_ACCELERATOR1_MAX:

            if (input_data.park_break_switch < 0)                      /* handbrake released */
            {
                return RSP_NOHBRAKE;
            }
            if (input_data.seat_switch_1 < 0)                         /* seat not activated */
            {
                return RSP_NOSEAT;
            }
            index = 0x03EA;
            data = input_data.adc_voltage[mcu_adc_Accelerator1] / can_resol_voltage_sensor;
            
            break;

        /*teachin of accelerator2 signal at pedal min position*/
        case REQ_TEACH_ACCELERATOR2_MIN:

            if (input_data.park_break_switch < 0)                      /* handbrake released */
            {
                return RSP_NOHBRAKE;
            }
            if (input_data.seat_switch_1 < 0)                         /* seat not activated */
            {
                return RSP_NOSEAT;
            }
            index = 0x03EB;
            data = input_data.adc_voltage[mcu_adc_Accelerator1] / can_resol_voltage_sensor;
            break;

        /*teachin of accelerator2 signal at pedal max position*/
        case REQ_TEACH_ACCELERATOR2_MAX:

            if (input_data.park_break_switch < 0)                      /* handbrake released */
            {
                return RSP_NOHBRAKE;
            }
            if (input_data.seat_switch_1 < 0)                         /* seat not activated */
            {
                return RSP_NOSEAT;
            }
            index = 0x03EC;
            data = input_data.adc_voltage[mcu_adc_Accelerator1] / can_resol_voltage_sensor;
            break;
            

                                                                                       
        /*teachin of steering angle signal at left mechanical stop*/
        case REQ_TEACH_STEERL:

            if (input_data.park_break_switch < 0)                      /* handbrake released */
            {
                return RSP_NOHBRAKE;
            }
            if (input_data.seat_switch_1 < 0)                         /* seat not activated */
            {
                return RSP_NOSEAT;
            }
            index = 0x03EF;
            data = input_data.adc_voltage[mcu_adc_SteerAngleA] / can_resol_voltage_sensor;

            break;

                                                                                       
        /*teachin of steering angle signal at right mechanical stop*/
        case REQ_TEACH_STEERR:

            if (input_data.park_break_switch < 0)                      /* handbrake released */
            {
                return RSP_NOHBRAKE;
            }
            if (input_data.seat_switch_1 < 0)                         /* seat not activated */
            {
                return RSP_NOSEAT;
            }
            index = 0x03F0;
            data = input_data.adc_voltage[mcu_adc_SteerAngleA] / can_resol_voltage_sensor;
            break;

                                                                                       
        /*teachin of steering angle signal at neutral mechanical stop*/
        case REQ_TEACH_STEER_NEUTRAL:
            if (input_data.park_break_switch < 0)                      /* handbrake released */
            {
                return RSP_NOHBRAKE;
            }
            if (input_data.seat_switch_1 < 0)                         /* seat not activated */
            {
                return RSP_NOSEAT;
            }
            index = 0x03F1;
            data = input_data.adc_voltage[mcu_adc_SteerAngleA] / can_resol_voltage_sensor;
            break;
            /*teachin of lift potentiometer signal at min position*/
        case REQ_TEACH_LIFT_POTENTIOMETER_MIN:
            if (input_data.park_break_switch < 0)                      /* handbrake released */
            {
                return RSP_NOHBRAKE;
            }
            if (input_data.seat_switch_1 < 0)                         /* seat not activated */
            {
                return RSP_NOSEAT;
            }
            index = 0x03ED;
            data = input_data.adc_voltage[mcu_adc_lift_Pot] / can_resol_voltage_sensor;

            break;

        /*teachin of lift potentiometer signal at max position*/
        case REQ_TEACH_LIFT_POTENTIOMETER_MAX:
            if (input_data.park_break_switch < 0)                      /* handbrake released */
            {
                return RSP_NOHBRAKE;
            }
            if (input_data.seat_switch_1 < 0)                         /* seat not activated */
            {
                return RSP_NOSEAT;
            }
            index = 0x03EE;
            data = input_data.adc_voltage[mcu_adc_lift_Pot] / can_resol_voltage_sensor;
            break;
        default:
            return RSP_ERRUNKNOWN;
    }


    switch(  paragen_set( &calibration_obj, index,&data,2,secacc_get_state()) )
    {
       case RC_ERROR_OPEN:                 return KWP_RESPONSE_CODE_INVALIDFORMAT;
       case RC_ERROR_READ_FAILS:           return KWP_RESPONSE_CODE_INVALIDFORMAT;
       case RC_ERROR_INVALID:              return KWP_RESPONSE_CODE_INVALIDFORMAT;
       case RC_ERROR_RANGE:                return KWP_RESPONSE_CODE_REQUESTOUTOFRANGE;
       case RC_ERROR_FILE_ACCESS:          return KWP_RESPONSE_CODE_ACCESSDENIED;
       case RC_ERROR:                      return KWP_RESPONSE_CODE_GENERALREJECT;
       case RC_SUCCESS:                    return KWP_RESPONSE_CODE_SUCCESS;
       default:                            return KWP_RESPONSE_CODE_SUCCESS;
    }

    
}


VO te_Conv2Diagno(VO)
{
    struct mon_parameter* diag = (struct mon_parameter *)mon_obj.ram_param;
    U32 data;
    diag->switches_current = Switches_Current;
    diag->tempmotinv1 = input_data.temperature_motor_1;
    diag->tempmotinv2 = input_data.temperature_motor_2;
    diag->ext5vsupply = input_data.adc_voltage[mcu_adc_5VExtSns] / can_resol_voltage_sensor;
    diag->ext13vsupply = input_data.adc_voltage[mcu_adc_13_7VSupply] / can_resol_voltage_sensor;
    diag->dclinkvolts = input_data.adc_voltage[mcu_adc_DcLink] / can_resol_voltage_drive;
    diag->accelerator1 = input_data.adc_voltage[mcu_adc_Accelerator1] / can_resol_voltage_sensor;
    diag->accelerator2 = input_data.adc_voltage[mcu_adc_Accelerator2] / can_resol_voltage_sensor;
    diag->steeranga = input_data.adc_voltage[mcu_adc_SteerAngleA] / can_resol_voltage_sensor;
    diag->steerangb = input_data.adc_voltage[mcu_adc_SteerAngleB] / can_resol_voltage_sensor;
    diag->reserver1volts = input_data.adc_voltage[mcu_adc_Reserve1] / can_resol_voltage_sensor;
    diag->reserver2volts = input_data.adc_voltage[mcu_adc_lift_Pot] / can_resol_voltage_sensor;
    diag->cutoffisocurrent = input_data.adc_voltage[mcu_adc_CurrentCutOffIso]/can_resol_current_sensor;
    diag->maincntcurrent = input_data.adc_voltage[mcu_adc_CurrentMainCont]/can_resol_current_sensor;
    diag->keyswitch = (input_data.adc_voltage[mcu_adc_KeySwitch]*(1.0f + calibration->key_switch_cal/1000.0f)) / can_resol_voltage_drive;
    diag->encoderspeed = input_data.motor_speed;
    diag->isocufoffpwm = (U32)output_data.iso_valve_pwm*100/0xffff;
    diag->maincntpwm = (U32)output_data.main_contactor_pwm*100/0xffff;
    diag->ext12vsupply = input_data.adc_voltage[mcu_adc_12VSupply] / can_resol_voltage_sensor;

    diag->component_work_time = time_diag_interface.Component_work_time;
    diag->driver_present_time = time_diag_interface.Driver_present_time;
    diag->fan1_open_time = time_diag_interface.Fan1_open_time;
    diag->fan2_open_time = time_diag_interface.Fan2_open_time;
    diag->forward_switch_time = time_diag_interface.Forward_switch_time;
    diag->neutral_switch_time = time_diag_interface.Neutral_switch_time;
    diag->reverse_switch_time = time_diag_interface.Reverse_switch_time;
    diag->traction_forward_time = time_diag_interface.Traction_forward_time;
    diag->traction_reverse_time = time_diag_interface.Traction_reverse_time;

    data = output_data.dcdc_control & 0x01;
    data |= (output_data.reset_error_cpu & 0x01) << 1;
    data |= (output_data.inverter_1_enable & 0x01) << 2;
    data |= (output_data.inverter_2_enable & 0x01) << 3;
    data |= (output_data.precharge & 0x01) << 4;
    data |= (output_data.fan_motor & 0x01) << 5;
    data |= (output_data.fan_controller & 0x01) << 6;
    data |= (output_data.buzzer & 0x01) << 7;
    data |= (output_data.led & 0x01) << 8;

    diag->switches_outputs = data;

}
                                                                                                  



/***********************************************************************************************************************
*                             Copyright 2020 Linde Material Handling. All rights reserved.                             *
***********************************************************************************************************************/

